package com.shanpin.shebao.web.service;

import java.io.IOException;
import java.security.MessageDigest;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.shanpin.core.http.HttpClient;
import com.shanpin.core.utils.JsonUtil;
import com.shanpin.shebao.web.model.JsapiSign;

@Service
public class WXJsapiService {

	private Map<String, String> map = new ConcurrentHashMap<>(8);
	static final String ACC_ID = "wxc4b1342b16e322da";
	static  String ACC_SECRET = "876e0d419fcadc5527d2f98d3999288c";
	private Logger log = LoggerFactory.getLogger(WXJsapiService.class);

	public JsapiSign wxJsapiSign(String url) throws Exception {
		if (url.indexOf("localhost") > -1) {
			url = url.replace("localhost", "192.168.1.99");
			url = url.replace(":8500", "");
		}
//		log.warn("url:{}", url);
		int timestamp = (int) (DateTime.now().getMillis() / 1000);
		JsapiSign sign = new JsapiSign(timestamp, ACC_ID);
		String expire_time = map.get("expire_time");
		if (StringUtils.isBlank(expire_time) || Integer.parseInt(expire_time) < timestamp) {
			TokenTicket token = getToken();
			if (null != token) {
				map.put("access_token", token.getAccess_token());
				map.put("expire_time", timestamp + token.getExpires_in()+"");
				token = getTicket(token.getAccess_token());
				if (null != token) {
					map.put("ticket", token.getTicket());
				}
			}
		}
		String signStr = "jsapi_ticket="+map.get("ticket")
			+"&noncestr="+sign.getNoncestr()
			+"&timestamp="+sign.getTimestamp()+"&url="+url;
		sign.setSignature(getSignature(signStr));
//		log.warn("signStr:{}  sign:{}", signStr, sign.getSignature());
		return sign;
	}

	private TokenTicket getToken() {
		String url = "https://api.weixin.qq.com/cgi-bin/token" + "?grant_type=client_credential&appid="
				+ ACC_ID + "&secret=" + ACC_SECRET;
		try {
			String resp = HttpClient.get(url);
			if (null != resp) {
				log.warn("getToken : " + resp);
				TokenTicket tt = JsonUtil.toT(resp, TokenTicket.class);
				if (tt.getErrcode() == 0) {
					return tt;
				}
			}
		} catch (IOException e) {
			log.error("", e);
		}
		return null;
	}
	
	private TokenTicket getTicket(String token) {
		String url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+token+"&type=jsapi";
		try {
			String resp = HttpClient.get(url);
			if (null != resp) {
				log.warn(resp);
				TokenTicket tt = JsonUtil.toT(resp, TokenTicket.class);
				if (tt.getErrcode() == 0) {
					return tt;
				}
			}
		} catch (IOException e) {
			log.error("", e);
		}
		return null;
	}
	

    private static String getSignature(String sKey) throws Exception {
        String ciphertext = null;
        MessageDigest md = MessageDigest.getInstance("SHA-1");
        byte[] digest = md.digest(sKey.toString().getBytes());
        ciphertext = byteToStr(digest);
        return ciphertext.toLowerCase();
    }


	/**
	 * 将字节数组转换为十六进制字符串
	 * 
	 * @param byteArray
	 * @return
	 */
	private static String byteToStr(byte[] byteArray) {
		String strDigest = "";
		for (int i = 0; i < byteArray.length; i++) {
			strDigest += byteToHexStr(byteArray[i]);
		}
		return strDigest;
	}

	/**
	 * 将字节转换为十六进制字符串
	 * 
	 * @param mByte
	 * @return
	 */
	private static String byteToHexStr(byte mByte) {
		char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A',
				'B', 'C', 'D', 'E', 'F' };
		char[] tempArr = new char[2];
		tempArr[0] = Digit[(mByte >>> 4) & 0X0F];
		tempArr[1] = Digit[mByte & 0X0F];

		String s = new String(tempArr);
		return s;
	}
}


class TokenTicket {
	private int errcode;
	private String errmsg;
	private String ticket;
	private String access_token;
	private int expires_in;
	
	public int getErrcode() {
		return errcode;
	}

	public void setErrcode(int errcode) {
		this.errcode = errcode;
	}

	public String getErrmsg() {
		return errmsg;
	}

	public void setErrmsg(String errmsg) {
		this.errmsg = errmsg;
	}

	public String getTicket() {
		return ticket;
	}

	public void setTicket(String ticket) {
		this.ticket = ticket;
	}

	public String getAccess_token() {
		return access_token;
	}

	public void setAccess_token(String access_token) {
		this.access_token = access_token;
	}

	public int getExpires_in() {
		return expires_in;
	}

	public void setExpires_in(int expires_in) {
		this.expires_in = expires_in;
	}

}
